Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/sticker_utils.py 33db12b971deeddf7b63d3e96fb5123a355b7986 (33db12b9) Text, 5.39 KB

T8b949e"""Validation and hashing for user sticker images stored per identity."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787base64
Tff7b72import T7ee787hashlib

Te6edf3MAX_STICKER_BYTES Tff7b72= T79c0ff512 Tff7b72* T79c0ff1024
Te6edf3MAX_STICKERS_PER_IDENTITY Tff7b72= T79c0ff2000

Te6edf3_ALLOWED_TYPES Tff7b72= Tffa657frozensetTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffjpgTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffgifTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwebpTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbmpTa5d6ff"Tb4b4b4}Tb4b4b4)

Te6edf3_TYPE_ALIASES Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffjpgTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpjpegTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffgifTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffgifTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffwebpTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffwebpTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffbmpTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffbmpTa5d6ff"Tb4b4b4,
Tb4b4b4}


Tff7b72def Td2a8ffnormalize_image_typeTb4b4b4(Te6edf3image_typeTb4b4b4: Tffa657str Tff7b72| Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Te6edf3image_typeTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3t Tff7b72= Tffa657strTb4b4b4(Te6edf3image_typeTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3t Tff7b72= Te6edf3tTff7b72.Td2a8ffremoveprefixTb4b4b4(Ta5d6ff"Ta5d6ffimage/Ta5d6ff"Tb4b4b4)
Te6edf3t Tff7b72= Te6edf3_TYPE_ALIASESTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tTb4b4b4, Te6edf3tTb4b4b4)
Tff7b72return Te6edf3t Tff7b72if Te6edf3t Tff7b72in Te6edf3_ALLOWED_TYPES Tff7b72else Tff7b72None


Tff7b72def Td2a8ffcontent_hash_hexTb4b4b4(Te6edf3image_bytesTb4b4b4: Tffa657bytesTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72return Te6edf3hashlibTff7b72.Td2a8ffsha256Tb4b4b4(Te6edf3image_bytesTb4b4b4)Tff7b72.Td2a8ffhexdigestTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffdetect_image_format_from_magicTb4b4b4(Te6edf3image_bytesTb4b4b4: Tffa657bytesTb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
T8b949e"""Detect image format from magic bytes.

Returns a normalized type key (png, jpeg, gif, webp, bmp), or None.
"""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3image_bytesTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72or Tffa657lenTb4b4b4(Te6edf3image_bytesTb4b4b4) Tff7b72< T79c0ff4Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3b Tff7b72= Tffa657bytesTb4b4b4(Te6edf3image_bytesTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3bTb4b4b4) Tff7b72>Tff7b72= T79c0ff8 Tff7b72and Te6edf3bTb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Tffea00\x89Ta5d6ffPNGTffea00\rTffea00\nTffea00\x1aTffea00\nTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffpngTa5d6ff"
Tff7b72if Tffa657lenTb4b4b4(Te6edf3bTb4b4b4) Tff7b72>Tff7b72= T79c0ff3 Tff7b72and Te6edf3bTb4b4b4[T79c0ff0Tb4b4b4:T79c0ff3Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Tffea00\xffTffea00\xd8Tffea00\xffTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffjpegTa5d6ff"
Tff7b72if Tffa657lenTb4b4b4(Te6edf3bTb4b4b4) Tff7b72>Tff7b72= T79c0ff6 Tff7b72and Te6edf3bTb4b4b4[T79c0ff0Tb4b4b4:T79c0ff6Tb4b4b4] Tff7b72in Tb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffGIF87aTa5d6ff"Tb4b4b4, Ta5d6ffbTa5d6ff"Ta5d6ffGIF89aTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffgifTa5d6ff"
Tff7b72if Tffa657lenTb4b4b4(Te6edf3bTb4b4b4) Tff7b72>Tff7b72= T79c0ff12 Tff7b72and Te6edf3bTb4b4b4[T79c0ff0Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffRIFFTa5d6ff" Tff7b72and Te6edf3bTb4b4b4[T79c0ff8Tb4b4b4:T79c0ff12Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffWEBPTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffwebpTa5d6ff"
Tff7b72if Tffa657lenTb4b4b4(Te6edf3bTb4b4b4) Tff7b72>Tff7b72= T79c0ff2 Tff7b72and Te6edf3bTb4b4b4[T79c0ff0Tb4b4b4:T79c0ff2Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffBMTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffbmpTa5d6ff"
Tff7b72return Tff7b72None


Tff7b72def Td2a8ffvalidate_sticker_payloadTb4b4b4(
Te6edf3image_bytesTb4b4b4: Tffa657bytesTb4b4b4,
Te6edf3image_typeTb4b4b4: Tffa657str Tff7b72| Tff7b72NoneTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657strTb4b4b4]Tb4b4b4:
T8b949e"""Returns (normalized_image_type, content_hash_hex).

Declared image_type must match the format detected from magic bytes; stored
type is the normalized detected format.

Raises ValueError with a short reason on invalid input.
"""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3image_bytesTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_image_bytesTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3image_bytesTb4b4b4) Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffempty_imageTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3image_bytesTb4b4b4) Tff7b72> Te6edf3MAX_STICKER_BYTESTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffimage_too_largeTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)

Te6edf3nt Tff7b72= Te6edf3normalize_image_typeTb4b4b4(Te6edf3image_typeTb4b4b4)
Tff7b72if Tff7b72not Te6edf3ntTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_image_typeTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)

Te6edf3detected Tff7b72= Te6edf3detect_image_format_from_magicTb4b4b4(Te6edf3image_bytesTb4b4b4)
Tff7b72if Tff7b72not Te6edf3detectedTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_image_signatureTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3detected Tff7b72!= Te6edf3ntTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffmagic_type_mismatchTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)

Te6edf3h Tff7b72= Te6edf3content_hash_hexTb4b4b4(Tffa657bytesTb4b4b4(Te6edf3image_bytesTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3detectedTb4b4b4, Te6edf3h


Te6edf3_EXPORT_FORMAT Tff7b72= Ta5d6ff"Ta5d6ffmeshchatx-stickersTa5d6ff"
Te6edf3_EXPORT_VERSION Tff7b72= T79c0ff1


Tff7b72def Td2a8ffvalidate_export_documentTb4b4b4(Te6edf3dataTb4b4b4: Tffa657objectTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4]Tb4b4b4:
T8b949e"""Parse and validate a sticker export JSON document.

Each sticker dict has ``name``, ``image_type``, ``image_bytes`` (base64), and
optional ``source_message_hash``.
"""
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3dataTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_documentTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffformatTa5d6ff"Tb4b4b4) Tff7b72!= Te6edf3_EXPORT_FORMATTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_formatTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3ver Tff7b72= Tffa657intTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffversionTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149KeyErrorTb4b4b4, Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4) Tff7b72as Te6edf3excTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffunsupported_versionTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4) Tff7b72from T7ee787exc
Tff7b72if Te6edf3ver Tff7b72!= Te6edf3_EXPORT_VERSIONTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffunsupported_versionTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3stickers Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffstickersTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3stickersTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid_stickers_arrayTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3outTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3iTb4b4b4, Te6edf3item Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3stickersTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3itemTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ffinvalid_sticker_at_Tffd700{Te6edf3iTffd700}Ta5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3name Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)
Te6edf3image_type Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4)
Te6edf3image_b64 Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimage_bytesTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3image_b64Tb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3image_b64Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ffmissing_image_bytes_at_Tffd700{Te6edf3iTffd700}Ta5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3base64Tff7b72.Td2a8ffb64decodeTb4b4b4(Te6edf3image_b64Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3validateTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4) Tff7b72as Te6edf3excTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ffinvalid_base64_at_Tffd700{Te6edf3iTffd700}Ta5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4) Tff7b72from T7ee787exc
Te6edf3src Tff7b72= Te6edf3itemTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsource_message_hashTa5d6ff"Tb4b4b4)
Te6edf3outTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3name Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3nameTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffimage_typeTa5d6ff"Tb4b4b4: Te6edf3image_typeTb4b4b4,
Ta5d6ff"Ta5d6ffimage_bytes_b64Ta5d6ff"Tb4b4b4: Te6edf3image_b64Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_message_hashTa5d6ff"Tb4b4b4: Te6edf3src Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3srcTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3out


Tff7b72def Td2a8ffbuild_export_documentTb4b4b4(Te6edf3stickersTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4]Tb4b4b4, Te6edf3exported_at_isoTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
T8b949e"""stickers: rows with name, image_type, image_bytes (base64 str), source_message_hash."""
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffformatTa5d6ff"Tb4b4b4: Te6edf3_EXPORT_FORMATTb4b4b4,
Ta5d6ff"Ta5d6ffversionTa5d6ff"Tb4b4b4: Te6edf3_EXPORT_VERSIONTb4b4b4,
Ta5d6ff"Ta5d6ffexported_atTa5d6ff"Tb4b4b4: Te6edf3exported_at_isoTb4b4b4,
Ta5d6ff"Ta5d6ffstickersTa5d6ff"Tb4b4b4: Te6edf3stickersTb4b4b4,
Tb4b4b4}


Tff7b72def Td2a8ffmime_for_image_typeTb4b4b4(Te6edf3normalized_typeTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffjpegTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffimage/jpegTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpngTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffimage/pngTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffgifTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffimage/gifTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffwebpTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffimage/webpTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffbmpTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffimage/bmpTa5d6ff"Tb4b4b4,
Tb4b4b4}Tff7b72.Td2a8ffgetTb4b4b4(Te6edf3normalized_typeTb4b4b4, Ta5d6ff"Ta5d6ffapplication/octet-streamTa5d6ff"Tb4b4b4)


Tff7b72def Td2a8ffsanitize_sticker_nameTb4b4b4(Te6edf3nameTb4b4b4: Tffa657str Tff7b72| Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3name Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3s Tff7b72= Ta5d6ff"Ta5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3ch Tff7b72for Te6edf3ch Tff7b72in Tffa657strTb4b4b4(Te6edf3nameTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3chTff7b72.Td2a8ffisprintableTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3sTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Te6edf3sTb4b4b4[Tb4b4b4:T79c0ff128Tb4b4b4]


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────